Skip to content

Conversation

runningcode
Copy link
Contributor

@runningcode runningcode commented Oct 15, 2025

Summary

Refactors the async checkForUpdate() API to return a Future<UpdateStatus> instead of using a callback pattern, and uses SentryExecutorService for background execution instead of spawning new threads.

Changes

  • API Change: Replaced callback-based checkForUpdate(UpdateCallback) with Future-based checkForUpdate()
  • Thread Management: Now uses SentryExecutorService instead of creating new threads for each call
  • Simplified API: Removed UpdateCallback interface entirely
  • Consistency: Aligns with existing SDK patterns for async operations
  • Resource Management: Leverages the shared thread pool to avoid creating unbounded threads

Benefits

  • More flexible API - callers control which thread to consume the result on
  • Better resource management through thread pooling
  • Cleaner API surface without callback confusion
  • Consistent with other SDK components that use SentryExecutorService

#skip-changelog

Fixes EME-413

🤖 Generated with Claude Code

Copy link

linear bot commented Oct 15, 2025

Copy link
Contributor

github-actions bot commented Oct 15, 2025

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 9b430e8

@runningcode runningcode requested a review from chromy October 15, 2025 14:50
onResult.onResult(result)
Thread {
val result = checkForUpdateBlocking()
onResult.onResult(result)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential bug: The onResult callback is not wrapped in a try-catch block, which could lead to an app crash if the user's implementation throws an exception.
  • Description: The onResult.onResult(result) call is executed on a background thread without any exception handling. If the user-provided onResult callback throws an exception, it will be uncaught on that thread, likely causing the entire application to crash. This is inconsistent with other parts of the SDK, such as the handling of OnDiscardCallback, where user-provided callbacks are defensively wrapped in a try-catch block to prevent such failures.

  • Suggested fix: Wrap the onResult.onResult(result) call within a try-catch (Throwable e) block. Log any caught exceptions using the provided logger, similar to the pattern used for other user callbacks in the SDK to protect the app from crashing.
    severity: 0.75, confidence: 0.95

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point but we should just crash here.

Copy link
Contributor

github-actions bot commented Oct 15, 2025

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 317.06 ms 373.48 ms 56.42 ms
Size 1.58 MiB 2.12 MiB 548.12 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
85d7417 347.21 ms 394.35 ms 47.15 ms
d364ace 411.72 ms 430.81 ms 19.10 ms
ee747ae 396.82 ms 441.67 ms 44.86 ms
bdbe1f4 380.66 ms 464.44 ms 83.78 ms
c8125f3 383.82 ms 441.66 ms 57.84 ms
ee747ae 386.94 ms 431.43 ms 44.49 ms
806307f 357.85 ms 424.64 ms 66.79 ms
ee747ae 554.98 ms 611.50 ms 56.52 ms
b3d8889 371.69 ms 432.96 ms 61.26 ms
7314dbe 437.83 ms 505.64 ms 67.81 ms

App size

Revision Plain With Sentry Diff
85d7417 1.58 MiB 2.10 MiB 533.44 KiB
d364ace 1.58 MiB 2.11 MiB 539.75 KiB
ee747ae 1.58 MiB 2.10 MiB 530.95 KiB
bdbe1f4 1.58 MiB 2.11 MiB 538.88 KiB
c8125f3 1.58 MiB 2.10 MiB 532.32 KiB
ee747ae 1.58 MiB 2.10 MiB 530.95 KiB
806307f 1.58 MiB 2.10 MiB 533.42 KiB
ee747ae 1.58 MiB 2.10 MiB 530.95 KiB
b3d8889 1.58 MiB 2.10 MiB 535.06 KiB
7314dbe 1.58 MiB 2.10 MiB 533.45 KiB

Previous results on branch: no/eme-413-async-update-check

Startup times

Revision Plain With Sentry Diff
9ac0631 402.78 ms 476.65 ms 73.87 ms
1f983f6 324.46 ms 452.26 ms 127.80 ms
9212043 373.06 ms 450.63 ms 77.57 ms
15641a2 394.08 ms 431.73 ms 37.65 ms
2e1e2d9 421.18 ms 549.46 ms 128.27 ms
b15d8fa 351.88 ms 417.20 ms 65.32 ms
b9cb481 381.29 ms 429.46 ms 48.17 ms

App size

Revision Plain With Sentry Diff
9ac0631 1.58 MiB 2.11 MiB 539.70 KiB
1f983f6 1.58 MiB 2.11 MiB 539.76 KiB
9212043 1.58 MiB 2.11 MiB 539.71 KiB
15641a2 1.58 MiB 2.11 MiB 539.76 KiB
2e1e2d9 1.58 MiB 2.11 MiB 539.76 KiB
b15d8fa 1.58 MiB 2.11 MiB 539.70 KiB
b9cb481 1.58 MiB 2.11 MiB 539.76 KiB

// TODO implement this in a async way
val result = checkForUpdateBlocking()
onResult.onResult(result)
public override fun checkForUpdate(): java.util.concurrent.Future<UpdateStatus> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, I guess as a nice follow-up we could have distribution-ktx that converts this to coroutines, but that's definitely not something we need to do now, if ever :)

Copy link
Member

@romtsn romtsn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for using the executor service!

cursor[bot]

This comment was marked as outdated.

runningcode and others added 8 commits October 20, 2025 16:04
…EME-413)

Implement async version of checkForUpdate that runs on a background thread
instead of blocking the calling thread. The callback is invoked on the
background thread, allowing callers to dispatch to main thread if needed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…ync checkForUpdate (EME-413)

Replace callback-based API with Future-based API to avoid confusion and improve consistency with SDK patterns. Use SentryExecutorService instead of spawning new threads to better manage resources.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…y (EME-413)

Replace CompletableFuture.completedFuture() with a custom CompletedFuture
implementation in NoOpDistributionApi to maintain Android API 21+ compatibility.
CompletableFuture was only added in Android API 24.

The new CompletedFuture follows the same pattern as existing CancelledFuture
implementations in the codebase and returns an immediately completed Future
with a result.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…EME-413)

Add explicit import for java.util.concurrent.Future and use short form
instead of fully qualified name in method signature.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…API (EME-413)

Update sample app to use the new Future-based checkForUpdate() method
instead of the old callback-based API. The Future is processed on a
background thread and results are posted back to the UI thread.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Improves code readability by importing Future instead of using fully qualified name.
Adds guidance comment suggesting developers convert the sample to their preferred
async library (RxJava, Coroutines, etc.) in production code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Applied spotlessApply formatting to wrap long comment line.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@runningcode runningcode force-pushed the no/eme-413-async-update-check branch from 7997cac to 9b430e8 Compare October 20, 2025 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants